<template><div><p>本文档最新版为 <a href="https://learnku.com/docs/laravel/10.x" target="_blank" rel="noopener noreferrer">10.x</a>，旧版本可能放弃维护，推荐阅读最新版！</p>
<h2 id="日志" tabindex="-1"><a class="header-anchor" href="#日志"><span>日志</span></a></h2>
<ul>
<li><a href="#introduction">简介</a></li>
<li><a href="#configuration">配置</a>
<ul>
<li><a href="#building-log-stacks">构建日志堆栈</a></li>
</ul>
</li>
<li><a href="#writing-log-messages">写日志消息</a>
<ul>
<li><a href="#writing-to-specific-channels">写入指定的通道</a></li>
</ul>
</li>
<li><a href="#advanced-monolog-channel-customization">先进的 Monolog 日志通道定制</a>
<ul>
<li><a href="#customizing-monolog-for-channels">自定义的 Monolog 通道</a></li>
<li><a href="#creating-monolog-handler-channels">创建 Monolog 处理通道</a></li>
<li><a href="#creating-channels-via-factories">通过工厂创建通道</a></li>
</ul>
</li>
</ul>
<h2 id="简介" tabindex="-1"><a class="header-anchor" href="#简介"><span>简介</span></a></h2>
<p>为了帮助你更多的了解应用程序中到底发生了什么，Laravel 提供了强大的日志服务，允许你将日志消息、系统错误日志记录到文件，甚至使用 Slack 通知到你的整个团队。</p>
<p>在 Laravel 框架中，Laravel 使用 <a href="https://github.com/Seldaek/monolog" target="_blank" rel="noopener noreferrer">Monolog</a> 库，它为各种强大的日志处理提供支持。Laravel 使配置这些处理程序变得简单，允许你混合并匹配它们自定义的应用程序日志处理。</p>
<h2 id="配置" tabindex="-1"><a class="header-anchor" href="#配置"><span>配置</span></a></h2>
<p>所有的应用程序日志系统配置都位于 <code v-pre>config/logging.php</code> 配置文件中。这个文件允许你配置你的应用程序日志通道，所以务必查看每个可用的通道及它们的选项。当然，我们将在下面回顾一些常用的选项。</p>
<p>默认情况下，Laravel 将使用 <code v-pre>stack</code> 去记录日志消息。stack 通道被用来将多个日志通道聚合到一个单一的通道中。关于堆栈的更多信息，查看 <a href="#building-log-stacks">以下文档</a>。</p>
<h4 id="配置通道名称" tabindex="-1"><a class="header-anchor" href="#配置通道名称"><span>配置通道名称</span></a></h4>
<p>默认情况下，Monolog 使用与当前环境匹配的『通道名称』进行实例化，比如 <code v-pre>production</code> 或者 <code v-pre>local</code>。要改变这个值，需添加一个 <code v-pre>name</code> 选项到你的通道配置中：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'stack'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'driver'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'stack'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'name'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'channel-name'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'channels'</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'single'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'slack'</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="可用的通道驱动" tabindex="-1"><a class="header-anchor" href="#可用的通道驱动"><span>可用的通道驱动</span></a></h4>
<table>
<thead>
<tr>
<th>名称</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td><code v-pre>stack</code></td>
<td>一个便于创建『多通道』通道的包装器</td>
</tr>
<tr>
<td><code v-pre>single</code></td>
<td>单个文件或者基于日志通道的路径 (<code v-pre>StreamHandler</code>)</td>
</tr>
<tr>
<td><code v-pre>daily</code></td>
<td>一个每天轮换的基于 Monolog 驱动的 <code v-pre>RotatingFileHandler</code></td>
</tr>
<tr>
<td><code v-pre>slack</code></td>
<td>一个基于 Monolog 驱动的 <code v-pre>SlackWebhookHandler</code></td>
</tr>
<tr>
<td><code v-pre>papertrail</code></td>
<td>一个基于 Monolog 驱动的 <code v-pre>SyslogUdpHandler</code></td>
</tr>
<tr>
<td><code v-pre>syslog</code></td>
<td>一个基于 Monolog 驱动的 <code v-pre>SyslogHandler</code></td>
</tr>
<tr>
<td><code v-pre>errorlog</code></td>
<td>一个基于 Monolog 驱动的 <code v-pre>ErrorLogHandler</code></td>
</tr>
<tr>
<td><code v-pre>monolog</code></td>
<td>一个可以使用任何支持 Monolog 处理程序的 Monolog 工厂驱动程序</td>
</tr>
<tr>
<td><code v-pre>custom</code></td>
<td>一个调用指定工厂创建通道的驱动程序</td>
</tr>
</tbody>
</table>
<blockquote>
<p>Tip：有关 <code v-pre>monolog</code> 和 <code v-pre>custom</code> 驱动，查看 <a href="#advanced-monolog-channel-customization">高级通道自定义</a></p>
</blockquote>
<h4 id="配置-single-和-daily-通道" tabindex="-1"><a class="header-anchor" href="#配置-single-和-daily-通道"><span>配置 Single 和 Daily 通道</span></a></h4>
<p><code v-pre>single</code> 和 <code v-pre>daily</code> 通道包含三个可选配置项：<code v-pre>bubble</code> 、<code v-pre>permission</code> 和 <code v-pre>locking</code>.</p>
<table>
<thead>
<tr>
<th>名称</th>
<th>描述</th>
<th>默认值</th>
</tr>
</thead>
<tbody>
<tr>
<td><code v-pre>bubble</code></td>
<td>消息处理后，指示消息是否推送到其他通道</td>
<td><code v-pre>true</code></td>
</tr>
<tr>
<td><code v-pre>permission</code></td>
<td>日志文件权限</td>
<td><code v-pre>0644</code></td>
</tr>
<tr>
<td><code v-pre>locking</code></td>
<td>写入之前尝试锁定日志文件</td>
<td><code v-pre>false</code></td>
</tr>
</tbody>
</table>
<h4 id="配置-papertrail-通道" tabindex="-1"><a class="header-anchor" href="#配置-papertrail-通道"><span>配置 Papertrail 通道</span></a></h4>
<p><code v-pre>papertrail</code> 通道需要 <code v-pre>url</code> 和 <code v-pre>端口</code> 配置选项。你可一从这里获取这些值 <a href="https://help.papertrailapp.com/kb/configuration/configuring-centralized-logging-from-php-apps/#send-events-from-php-app" target="_blank" rel="noopener noreferrer">Papertrail</a> 。</p>
<p>####配置 Slack 通道</p>
<p><code v-pre>slack</code> 通道需要 <code v-pre>url</code> 配置选项。这个 URL 应当与你为 Slack 团队配置的一个 <a href="https://slack.com/apps/A0F7XDUAZ-incoming-webhooks" target="_blank" rel="noopener noreferrer">incoming webhook</a> 相匹配。</p>
<h3 id="构建日志堆栈" tabindex="-1"><a class="header-anchor" href="#构建日志堆栈"><span>构建日志堆栈</span></a></h3>
<p>前面说过， <code v-pre>stack</code> 驱动允许你在单一日志通道中整合多个通道。让我们通过一个产品级应用的配置实例来看看如何使用日志堆栈：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'channels'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'stack'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'driver'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'stack'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'channels'</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'syslog'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'slack'</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span>
<span class="line">    <span class="token string single-quoted-string">'syslog'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'driver'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'syslog'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'level'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'debug'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span>
<span class="line">    <span class="token string single-quoted-string">'slack'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'driver'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'slack'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'url'</span> <span class="token operator">=></span> <span class="token function">env</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'LOG_SLACK_WEBHOOK_URL'</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'username'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'Laravel Log'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'emoji'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">':boom:'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'level'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'critical'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>我们来分析这个配置。首先要注意的是 <code v-pre>stack</code> 通过借助它的 <code v-pre>channels</code> 选项聚合了另外两个通道： <code v-pre>syslog</code> 和 <code v-pre>slack</code> 。因此，在记录日志消息时，这两个通道都有机会完成日志消息记录：</p>
<h4 id="日志级别" tabindex="-1"><a class="header-anchor" href="#日志级别"><span>日志级别</span></a></h4>
<p>请留意上面例子中 <code v-pre>syslog</code> 和 <code v-pre>slack</code> 中存在的 <code v-pre>level</code> 配置项。这个选项决定了需要被该通道记录的日志的最低 「级别」。Monolog （一个功能强劲的 Laravel 日志服务）接受定义在 <a href="https://tools.ietf.org/html/rfc5424" target="_blank" rel="noopener noreferrer">RFC 5424 specification</a> 中的全部级别： <strong>emergency</strong>、<strong>alert</strong>、 <strong>critical</strong>、 <strong>error</strong>、 <strong>warning</strong>、 <strong>notice</strong>、 <strong>info</strong> 和 <strong>debug</strong>。</p>
<p>假设我们使用 <code v-pre>debug</code> 方法记录日志消息：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Log</span><span class="token operator">::</span><span class="token function">debug</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'An informational message.'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>根据我们的配置， <code v-pre>syslog</code> 通道将把该消息记录到系统日志；不过因为错误消息不是 <code v-pre>critical</code> 或更高级别，它将不会被发送到 Slack。如果我们记录一条 <code v-pre>emergency</code> 消息，它将被发送给系统日志和 Slack，因为 <code v-pre>emergency</code> 的级别高于两个通道的最低级别限制：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Log</span><span class="token operator">::</span><span class="token function">emergency</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'The system is down!'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h2 id="写日志消息" tabindex="-1"><a class="header-anchor" href="#写日志消息"><span>写日志消息</span></a></h2>
<p>可以使用 <code v-pre>Log</code> <a href="https://learnku.com/docs/laravel/6.x/facades" target="_blank" rel="noopener noreferrer">facade</a> 将信息写入日志。如前所述，日志提供定义在 <a href="https://tools.ietf.org/html/rfc5424" target="_blank" rel="noopener noreferrer">RFC 5424 specification</a> 中的可用日志级别： <strong>emergency</strong>、 <strong>alert</strong>、 <strong>critical</strong>、 <strong>error</strong>、 <strong>warning</strong>、 <strong>notice</strong>、 <strong>info</strong> 和 <strong>debug</strong>：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Log</span><span class="token operator">::</span><span class="token function">emergency</span><span class="token punctuation">(</span><span class="token variable">$message</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token class-name static-context">Log</span><span class="token operator">::</span><span class="token function">alert</span><span class="token punctuation">(</span><span class="token variable">$message</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token class-name static-context">Log</span><span class="token operator">::</span><span class="token function">critical</span><span class="token punctuation">(</span><span class="token variable">$message</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token class-name static-context">Log</span><span class="token operator">::</span><span class="token function">error</span><span class="token punctuation">(</span><span class="token variable">$message</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token class-name static-context">Log</span><span class="token operator">::</span><span class="token function">warning</span><span class="token punctuation">(</span><span class="token variable">$message</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token class-name static-context">Log</span><span class="token operator">::</span><span class="token function">notice</span><span class="token punctuation">(</span><span class="token variable">$message</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token class-name static-context">Log</span><span class="token operator">::</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token variable">$message</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token class-name static-context">Log</span><span class="token operator">::</span><span class="token function">debug</span><span class="token punctuation">(</span><span class="token variable">$message</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>因此，你可以调用这些方法中的任一方法记录相应级别的日志。默认情况下，消息被写入到在 <code v-pre>config/logging.php</code> 配置文件中定义的默认日志通道：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Controllers</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>User</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Log</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Controllers<span class="token punctuation">\</span>Controller</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">UserController</span> <span class="token keyword">extends</span> <span class="token class-name">Controller</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 显示给定用户的配置信息。</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@param</span>  <span class="token class-name"><span class="token keyword">int</span></span>  <span class="token parameter">$id</span></span>
<span class="line">     * <span class="token keyword">@return</span> <span class="token class-name">Response</span></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">showProfile</span><span class="token punctuation">(</span><span class="token variable">$id</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token class-name static-context">Log</span><span class="token operator">::</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'Showing user profile for user: '</span><span class="token operator">.</span><span class="token variable">$id</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">        <span class="token keyword">return</span> <span class="token function">view</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'user.profile'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'user'</span> <span class="token operator">=></span> <span class="token class-name static-context">User</span><span class="token operator">::</span><span class="token function">findOrFail</span><span class="token punctuation">(</span><span class="token variable">$id</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="上下文信息" tabindex="-1"><a class="header-anchor" href="#上下文信息"><span>上下文信息</span></a></h4>
<p>可以将上下文数据数组传递给日志方法。这些信息将被格式化，并与日志消息一直显示：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Log</span><span class="token operator">::</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'User failed to login.'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'id'</span> <span class="token operator">=></span> <span class="token variable">$user</span><span class="token operator">-></span><span class="token property">id</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h3 id="写入指定通道" tabindex="-1"><a class="header-anchor" href="#写入指定通道"><span>写入指定通道</span></a></h3>
<p>有时候你可能希望将消息写入到应用默认通道之外的通道中。可以使用 <code v-pre>Log</code> facade 的 <code v-pre>channel</code> 方法获取定义在配置文件中的任一通道并将消息写入其中 ：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Log</span><span class="token operator">::</span><span class="token function">channel</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'slack'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'Something happened!'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>如果想要创建一个由多通道构成的按需记录的堆栈，可以使用 <code v-pre>stack</code> 方法：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Log</span><span class="token operator">::</span><span class="token function">stack</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'single'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'slack'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'Something happened!'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h2 id="高度自定义-monolog-通道" tabindex="-1"><a class="header-anchor" href="#高度自定义-monolog-通道"><span>高度自定义 Monolog 通道</span></a></h2>
<h3 id="为通道自定义-monolog" tabindex="-1"><a class="header-anchor" href="#为通道自定义-monolog"><span>为通道自定义 Monolog</span></a></h3>
<p>有时需要完全控制已存在通道的 Monolog： 比如，你可能想要为给定通道的日志处理配置自定义的 Monolog <code v-pre>FormatterInterface</code> 实现：</p>
<p>先在通道配置中定义一个 <code v-pre>tap</code> 数组。 <code v-pre>tap</code> 数组包含一个在通道创建后有机会用于自定义 Monolog 实例的类列表：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'single'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'driver'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'single'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'tap'</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token class-name class-name-fully-qualified static-context">App<span class="token punctuation">\</span>Logging<span class="token punctuation">\</span>CustomizeFormatter</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'path'</span> <span class="token operator">=></span> <span class="token function">storage_path</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'logs/laravel.log'</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'level'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'debug'</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>一旦在通道中有了 <code v-pre>tap</code> 选项配置，就要准备用于自定义 Monolog 实例的类。这种类这需要一个方法： <code v-pre>__invoke</code>，它接受一个 <code v-pre>Illuminate\Log\Logger</code> 实例作为其参数。 <code v-pre>Illuminate\Log\Logger</code> 实例将所有方法调用代理到基础的 Monolog 实例：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Logging</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">CustomizeFormatter</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 自定义给定的日志实例。</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@param</span>  <span class="token class-name"><span class="token punctuation">\</span>Illuminate<span class="token punctuation">\</span>Log<span class="token punctuation">\</span>Logger</span>  <span class="token parameter">$logger</span></span>
<span class="line">     * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">void</span></span></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">__invoke</span><span class="token punctuation">(</span><span class="token variable">$logger</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$logger</span><span class="token operator">-></span><span class="token function">getHandlers</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">as</span> <span class="token variable">$handler</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">            <span class="token variable">$handler</span><span class="token operator">-></span><span class="token function">setFormatter</span><span class="token punctuation">(</span><span class="token operator">...</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token punctuation">}</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p>Tip：所有的 “tap” 类都是由 <a href="https://learnku.com/docs/laravel/6.x/container" target="_blank" rel="noopener noreferrer">服务容器</a> 解析的，因此任何依赖它们的构造器都会自动被注入。</p>
</blockquote>
<h3 id="创建-monolog-处理器通道" tabindex="-1"><a class="header-anchor" href="#创建-monolog-处理器通道"><span>创建 Monolog 处理器通道</span></a></h3>
<p>Monolog 多种 <a href="https://github.com/Seldaek/monolog/tree/master/src/Monolog/Handler" target="_blank" rel="noopener noreferrer">可用处理器</a>。在某些情况下，你会希望仅创建一个带有指定处理器的 Monolog 驱动的日志类型。这些通道可以使用 <code v-pre>monolog</code> 驱动创建。</p>
<p>在使用 <code v-pre>monolog</code> 驱动时， <code v-pre>handler</code> 配置项用于指定被实例化的处理器。如果该处理器的构造器需要参数，可以使用可选的 <code v-pre>with</code> 配置项来指定：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'logentries'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'driver'</span>  <span class="token operator">=></span> <span class="token string single-quoted-string">'monolog'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'handler'</span> <span class="token operator">=></span> <span class="token class-name class-name-fully-qualified static-context">Monolog<span class="token punctuation">\</span>Handler<span class="token punctuation">\</span>SyslogUdpHandler</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'with'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'host'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'my.logentries.internal.datahubhost.company.com'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'port'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'10000'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="monolog-格式化" tabindex="-1"><a class="header-anchor" href="#monolog-格式化"><span>Monolog 格式化</span></a></h4>
<p>使用 <code v-pre>monolog</code> 驱动时，Monolog 的 <code v-pre>LineFormatter</code> 用于默认的格式化处理器。当然，你也可以使用 <code v-pre>formatter</code> and <code v-pre>formatter_with</code> 配置项自定义格式化处理器类型：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'browser'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'driver'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'monolog'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'handler'</span> <span class="token operator">=></span> <span class="token class-name class-name-fully-qualified static-context">Monolog<span class="token punctuation">\</span>Handler<span class="token punctuation">\</span>BrowserConsoleHandler</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'formatter'</span> <span class="token operator">=></span> <span class="token class-name class-name-fully-qualified static-context">Monolog<span class="token punctuation">\</span>Formatter<span class="token punctuation">\</span>HtmlFormatter</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'formatter_with'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'dateFormat'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'Y-m-d'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果所用的 Monolog 处理器能够提供自带的格式代处理器，可以将 <code v-pre>formatter</code> 配置项指定为 <code v-pre>default</code>:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'newrelic'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'driver'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'monolog'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'handler'</span> <span class="token operator">=></span> <span class="token class-name class-name-fully-qualified static-context">Monolog<span class="token punctuation">\</span>Handler<span class="token punctuation">\</span>NewRelicHandler</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'formatter'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'default'</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="通过工厂创建渠道" tabindex="-1"><a class="header-anchor" href="#通过工厂创建渠道"><span>通过工厂创建渠道</span></a></h3>
<p>如果你想定义一个完全自定义的通道，你可以完全控制 Monolog 的实例化和配置，你可以在 <code v-pre>config/logging.php</code> 配置文件中指定 <code v-pre>custom</code> 驱动程序类型。 你的配置应该包含一个 <code v-pre>via</code> 选项，指向将被调用以创建 Monolog 实例的工厂类：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'channels'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'custom'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'driver'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'custom'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'via'</span> <span class="token operator">=></span> <span class="token class-name class-name-fully-qualified static-context">App<span class="token punctuation">\</span>Logging<span class="token punctuation">\</span>CreateCustomLogger</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>一旦配置了 <code v-pre>custom</code> 通道，就可以定义创建 Monolog 实例的类。 这个类只需要一个方法： <code v-pre>__invoke</code> ，它就可以返回 Monolog 实例：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Logging</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Monolog<span class="token punctuation">\</span>Logger</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">CreateCustomLogger</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 创建一个 Monolog 实例.</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@param</span>  <span class="token class-name"><span class="token keyword">array</span></span>  <span class="token parameter">$config</span></span>
<span class="line">     * <span class="token keyword">@return</span> <span class="token class-name"><span class="token punctuation">\</span>Monolog<span class="token punctuation">\</span>Logger</span></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">__invoke</span><span class="token punctuation">(</span><span class="token keyword type-hint">array</span> <span class="token variable">$config</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Logger</span><span class="token punctuation">(</span><span class="token operator">...</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p>本译文仅用于学习和交流目的，转载请务必注明文章译者、出处、和本文链接<br>
我们的翻译工作遵照 <a href="https://learnku.com/docs/guide/cc4.0/6589" target="_blank" rel="noopener noreferrer">CC 协议</a>，如果我们的工作有侵犯到您的权益，请及时联系我们。</p>
</blockquote>
<hr>
<blockquote>
<p>原文地址：<a href="https://learnku.com/docs/laravel/6.x/logging/5146" target="_blank" rel="noopener noreferrer">https://learnku.com/docs/laravel/6.x/log...</a></p>
<p>译文地址：<a href="https://learnku.com/docs/laravel/6.x/logging/5146" target="_blank" rel="noopener noreferrer">https://learnku.com/docs/laravel/6.x/log...</a></p>
</blockquote>
</div></template>


